﻿#ifndef _DATA_RING_BUF_
#define _DATA_RING_BUF_

#include "moodycamel/concurrentqueue.h"

static const std::size_t KBufSize = 1024 * 10; // 无锁队列大小（总长度,表示一共能容纳多少个元素）

// 单生产者，单消费者环形缓冲，用于数据采集线程和数据发送线程交互
// 无锁队列用于存放数据
template<class T>
class DataRingBuf
{
public:
    // size为队列总长度,表示一共能容纳多少个元素
    DataRingBuf(std::size_t size)
    {
        m_queue = new moodycamel::ConcurrentQueue<T>(size);
        m_maxSize = size;
    };

    ~DataRingBuf()
    {
        moodycamel::ConcurrentQueue<T> empty;
        m_queue->swap(empty);
    };

    // 入队操作，将rd这个元素入队到队列里去，如果超过了队列大小会自动再分配内存,入队失败返回false，成功则返回true
    inline bool enqueue(T &&rd)
    {
        if (size() < m_maxSize)
            return m_queue->enqueue(rd);
        else
            return false;
    };

    // 入队操作,将rd这个元素入队到队列里去:如果已存储元素超过队列容量则不插入返回false，否则返回插入并返回true
    inline bool try_enqueue(T &&rd) { return m_queue->try_enqueue(rd); };

    // 出队操作,将出队的元素放在rd中:如果没有出队的元素则返回false，如果有出队的元素则返回true并将该元素赋值到rd中去
    inline bool try_dequeue(T &&rd) { return m_queue->try_dequeue(rd); }

    // 返回目前已经生产而尚未被消费的元素的个数
    inline std::size_t size() { return m_queue->size_approx(); }

private:
    moodycamel::ConcurrentQueue<T> *m_queue;
    uint64_t m_maxSize; // 元素最大的大小
};
#endif //_DATA_RING_BUF_